package com.dnjn.happiness.emo.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dnjn.happiness.common.core.constant.Constants;
import com.dnjn.happiness.common.core.constant.SecurityConstants;
import com.dnjn.happiness.common.core.domain.R;
import com.dnjn.happiness.common.core.model.HxBeanSeed;
import com.dnjn.happiness.common.core.utils.StringUtils;
import com.dnjn.happiness.common.core.utils.bean.BeanUtils;
import com.dnjn.happiness.common.log.annotation.Log;
import com.dnjn.happiness.common.cloud.controller.BaseController;
import com.dnjn.happiness.common.core.web.domain.AjaxResult;
import com.dnjn.happiness.common.core.utils.poi.ExcelUtil;
import com.dnjn.happiness.common.log.enums.BusinessType;
import com.dnjn.happiness.common.security.annotation.InnerAuth;
import com.dnjn.happiness.common.security.annotation.RequiresPermissions;
import com.dnjn.happiness.common.security.utils.SecurityUtils;
import com.dnjn.happiness.emo.api.RemoteHlbeanTypeService;
import com.dnjn.happiness.emo.api.domain.EmoAvgScoreDaily;
import com.dnjn.happiness.emo.api.model.EmoUserBean;
import com.dnjn.happiness.emo.api.model.EmoUserVO;
import com.dnjn.happiness.emo.api.model.HlbeanTypeVO;
import com.dnjn.happiness.emo.domain.Hlbean;
import com.dnjn.happiness.emo.domain.User;
import com.dnjn.happiness.emo.domain.vo.ScoreSpreadVO;
import com.dnjn.happiness.emo.service.IEmoAvgScoreDailyService;
import com.dnjn.happiness.emo.service.IHlbeanService;
import com.dnjn.happiness.emo.service.IUserService;
import com.dnjn.happiness.system.api.RemoteConfigService;
import com.dnjn.happiness.system.api.domain.UserSituationVO;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.NumberFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * Controller
 * 
 * @author happiness
 * @date 2023-10-13
 */
@Tag(name = "emo user ", description = "")
@RestController
@RequestMapping("/user")
public class UserController extends BaseController
{
    @Autowired
    private IUserService userService;

    @Autowired
    private IHlbeanService hlbeanService;

    @Autowired
    private RemoteConfigService configService;


    @Autowired
    private RemoteHlbeanTypeService hlbeanTypeService;

    @Autowired
    private IEmoAvgScoreDailyService dailyService;

    @InnerAuth
    @GetMapping("/updateHappinessScoreByUserId/{userId}/{hscore}")
    public void updateHappinessScoreByUserId(@PathVariable Long userId, @PathVariable Integer hscore) {
        boolean update = userService.lambdaUpdate().eq(User::getDeleted, Constants.UNDELETED)
                .eq(User::getUserId, userId).set(User::getHappinessScore, hscore).update();
    }

    @InnerAuth
    @GetMapping("/updateWorkDate/{userId}")
    public R<Boolean> updateWorkDate(@PathVariable Long userId) {
        return R.ok(userService.updateWorkDate(userId));
    }

    @InnerAuth
    @GetMapping("/selectByLimit/{index}/{num}")
    public R<List<EmoUserBean> > selectByLimit(@PathVariable int index,@PathVariable int num) {
        return R.ok(userService.selectByLimit(index,num));
    }

    @InnerAuth
    @GetMapping("/getCount")
    public R<Long> getCount() {
        return R.ok(userService.lambdaQuery().eq(User::getDeleted, "0").count());
    }


    @InnerAuth
    @GetMapping("/emptytheHappyBeansToday")
    public void emptytheHappyBeansToday() {
        userService.lambdaUpdate().set(User::getHlbeanToday, 0L).update();
    }

    @InnerAuth
    @GetMapping("/selectUserList")
    public R<List<EmoUserVO>> selectUserList() {
        List<User> userList = userService.selectUserList();
        List<EmoUserVO> voList = new ArrayList<>();
        userList.forEach(item->{
            EmoUserVO vo = new EmoUserVO();
            BeanUtils.copyBeanProp(vo,item);
            voList.add(vo);
        });
        return R.ok(voList);
    }

    @InnerAuth
    @GetMapping("/saveEmoUserById/{userId}")
    public R<EmoUserVO> saveEmoUserById(@PathVariable Long userId) {
        EmoUserVO vo = new EmoUserVO();
        User user = userService.saveEmoUser(userId);
        if (null != user){
            BeanUtils.copyBeanProp(vo,user);
        }
        return R.ok(vo);
    }

    @InnerAuth
    @GetMapping("/updateHappinessScores/{userId}/{happinessScores}")
    public R<Boolean> updateHappinessScores(@PathVariable("userId") Long userId, @PathVariable("happinessScores") Integer happinessScores) {
        return R.ok(userService.updateHappinessScores(userId,happinessScores));
    }

    @InnerAuth
    @GetMapping("/getInfoByUserId/{userId}")
    public R<User> getInfoByUserId(@PathVariable Long userId) {
        return R.ok(userService.lambdaQuery().eq(User::getUserId, userId).one());
    }

    @InnerAuth
    @PostMapping("/saveEmoUser")
    public R<User> saveEmoUser(@RequestBody HxBeanSeed beanSeed) {
        User user = new User()
                .setUserId(beanSeed.getUserId())
                .setHlbean(0L)
                .setHappinessScore(0L)
                .setHlbeanToday(0L)
                ;
        userService.save(user);
        return R.ok(user);
    }

    @InnerAuth
    @PostMapping("/delEmoUser")
    public void delEmoUser(@RequestBody HxBeanSeed beanSeed) {
        userService.lambdaUpdate().set(User::getDeleted, "1").eq(User::getUserId, beanSeed.getUserId()).update();
    }

    @InnerAuth
    @PostMapping("/updateHBean")
    public R<Boolean> updateHBean(@RequestBody HxBeanSeed seed) {
        Long userId = seed.getUserId();
        String code = seed.getRiskType();
        String strFlag = "";
        R<String> result = configService.configKeyApi("biz.happinessBean.enabled", SecurityConstants.INNER);
        if(StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())){
            strFlag = result.getData();
        }
        if ("true".equals(strFlag)) {
            HlbeanTypeVO hlbeanType = null;
            R<HlbeanTypeVO> resultVO = hlbeanTypeService.getHlbeanTypeByCode(code,SecurityConstants.INNER);
            if(StringUtils.isNotNull(resultVO) && StringUtils.isNotNull(resultVO.getData())){
                hlbeanType = resultVO.getData();
            }
            Integer currValue = 0;
            if (null != hlbeanType){
                currValue = hlbeanType.getHlbeanValue();
            }
            User emoUser = userService.lambdaQuery().eq(User::getUserId, userId).one();
            if (null == emoUser) {
                emoUser = userService.saveEmoUser(userId);
            }
            //更新emoUser的快乐豆
            userService.lambdaUpdate()
                    .set(User::getHlbeanToday, (emoUser.getHlbeanToday() == null ? 0 : emoUser.getHlbeanToday()) + currValue)
                    .set(User::getHlbean, (emoUser.getHlbean() == null ? 0 : emoUser.getHlbean()) + currValue)
                    .eq(User::getUserId, userId).update();
            //新增hlbean记录
            Hlbean hlbean = new Hlbean().
                    setUserId(userId)
                    .setHlbeanCode(code)
                    .setCurrDatetime(LocalDateTime.now())
                    .setCurrDate(LocalDate.now())
                    .setHlbeanCurr(currValue)
                    .setHlbeanBefore(emoUser.getHlbean() == null ? 0 : emoUser.getHlbean().intValue())
                    .setHlbeanAfter((emoUser.getHlbean() == null ? 0 : emoUser.getHlbean().intValue()) + currValue);
            hlbeanService.save(hlbean);
        }
        return R.ok(true);
    }

    /**
     * 查询列表
     */
    @PostMapping("/list")
    public AjaxResult list(User user, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size)
    {
        Page page = Page.of(current, size);
        Page<User> list = userService.page(page,Wrappers.query(user));
        return success(list);
    }

    /**
     * 导出列表
     */
    @Log(title = "", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, User user)
    {
        List<User> list = userService.list(Wrappers.query(user));
        ExcelUtil<User> util = new ExcelUtil<User>(User.class);
        util.exportExcel(response, list, "数据");
    }

    /**
     * 获取详细信息
     */
    @GetMapping(value = "/{userId}")
    public AjaxResult get(@PathVariable("userId") Long userId)
    {
        return success(userService.getById(userId));
    }

    /**
     * 新增
     */
    @Log(title = "", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody User user)
    {
        user.setCreateBy(SecurityUtils.getUsername());
        return toAjax(userService.save(user));
    }

    /**
     * 修改
     */
    @Log(title = "", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody User user)
    {
        return toAjax(userService.updateById(user));
    }

    /**
     * 删除
     */
    @Log(title = "", businessType = BusinessType.DELETE)
	@DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds)
    {
        return toAjax(userService.removeBatchByIds(Arrays.asList( userIds)));
    }

    /**
     * 首页当日快乐值人员分布图
     */
    @RequiresPermissions("@ss.hasPermi('score:weekly:query')")
    @GetMapping("/getDailyHappinessScore")
    @Log(title = "biz", businessType = BusinessType.SELECT)
    public AjaxResult getDailyHappinessScore(@RequestParam(required = false) Long deptId) {
        if (Objects.isNull(deptId)) {
            deptId = SecurityUtils.getLoginUser().getDeptId();
        }
        List<ScoreSpreadVO> list = new ArrayList<>();
        list.add(new ScoreSpreadVO().setStartInterval(300).setEndInterval(400));
        list.add(new ScoreSpreadVO().setStartInterval(400).setEndInterval(500));
        list.add(new ScoreSpreadVO().setStartInterval(500).setEndInterval(600));
        list.add(new ScoreSpreadVO().setStartInterval(600).setEndInterval(700));
        list.add(new ScoreSpreadVO().setStartInterval(700).setEndInterval(800));
        list.add(new ScoreSpreadVO().setStartInterval(800).setEndInterval(900));
        //查询沟通临界值。
        String configValueByKey = null;
        R<String> thresholdResult = configService.getThresholdDateaApi(SecurityConstants.INNER);
        if (StringUtils.isNotNull(thresholdResult) && StringUtils.isNotNull(thresholdResult.getData())){
            configValueByKey = thresholdResult.getData();
        }
        if (StringUtils.isEmpty(configValueByKey)) {
            return AjaxResult.error("快乐值临界值为空！");
        }
        NumberFormat format = NumberFormat.getInstance();
        format.setMaximumFractionDigits(2);
        for (ScoreSpreadVO vo : list) {
            vo.setRequiredCommunicateCount(userService.selectRequiredCommunicateCount(vo.getStartInterval(), vo.getEndInterval(), Integer.parseInt(configValueByKey), deptId));
            vo.setNormalCount(userService.selectnormalCount(vo.getStartInterval(), vo.getEndInterval(), Integer.parseInt(configValueByKey), deptId));
            vo.setTotalCount(vo.getRequiredCommunicateCount() + vo.getNormalCount());
            if (0 == vo.getTotalCount()) {
                vo.setRatioRequiredCommunicate("0%");
                vo.setRatioNormal("0%");
            } else {
                vo.setRatioRequiredCommunicate(format.format((float) vo.getRequiredCommunicateCount() / (float) vo.getTotalCount() * 100) + "%");
                vo.setRatioNormal(format.format((float) vo.getNormalCount() / (float) vo.getTotalCount() * 100) + "%");
            }
        }
        return success(list);
    }

    /**
     * 首页人员情况 默认分页查询所有的人员，参数区间值（不必填）
     * showType:展示类型，不必填。展示需沟通类型（communicat），展示正常类型(normal)
     */
    @RequiresPermissions("@ss.hasPermi('score:weekly:query')")
    @PostMapping("/getHomePageUserList")
    @Log(title = "biz", businessType = BusinessType.SELECT)
    public AjaxResult getHomePageUserList(@Parameter(description = "区间开始值") @RequestParam(value = "startInterval", required = false) Integer startInterval,
                                          @Parameter(description = "区间结束值") @RequestParam(value = "endInterval", required = false) Integer endInterval,
                                          @Parameter(description = "展示类型：需沟通类型（communicate）| 正常类型(normal)") @RequestParam(value = "showType", required = false) String showType,
                                          @RequestParam(value = "deptId", required = false) Long deptId,
                                          @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {

        HashMap<String, Object> map = new HashMap<>();
        if (StringUtils.isNotNull(startInterval) && StringUtils.isNotNull(endInterval)) {
            map.put("startInterval", startInterval);
            map.put("endInterval", endInterval);
        }
        String criticalValueStr = null;
        R<String> thresholdResult = configService.getThresholdDateaApi(SecurityConstants.INNER);
        if (StringUtils.isNotNull(thresholdResult) && StringUtils.isNotNull(thresholdResult.getData())){
            criticalValueStr = thresholdResult.getData();
        }
        //临界值
        int criticalValue = Integer.parseInt(criticalValueStr);
        if (StringUtils.isNotEmpty(showType)) {
            map.put("showType", showType);
            map.put("threshold", criticalValue);
        }
        if (Objects.isNull(deptId)) {
            deptId = SecurityUtils.getLoginUser().getDeptId();
        }
        map.put("deptId", deptId);
        Page page = Page.of(current, size);
        Integer requiredCommunicateCount = userService.selectRequiredCommunicateCount(startInterval, endInterval, Integer.parseInt(criticalValueStr), deptId);
        Page<UserSituationVO> voPage = userService.getHomePage(page, map);
        for (UserSituationVO vo : voPage.getRecords()) {
            vo.setRequiredCommunicateCount(requiredCommunicateCount);
            Long currScore = vo.getHappinessScore();
            Long userId = vo.getUserId();
            //查询较昨日波动
            EmoAvgScoreDaily dto = dailyService.selectDailyScoreAvgByUserId(userId);
            //快乐值波动
            if (StringUtils.isNull(dto)) {
                vo.setHappinessScoreChange(0L);
            } else {
                vo.setHappinessScoreChange(currScore - dto.getScoreAvg().longValue());
            }
            //查询当前状态 先判断当前快乐值是否是需要沟通
            if (currScore < criticalValue) {
                Integer value = userService.selectDelayDaysByUserId(userId);
                vo.setStatus(StringUtils.isNull(value) || value == 0 ? "需沟通" : "延迟" + value + "天");
            } else {
                vo.setStatus("正常");
            }
            //是否评价，
            LocalDateTime appraiseTime = vo.getAppraiseTime();
            if (Objects.isNull(appraiseTime)) {
                vo.setHasAppraise(true);
            } else {
                LocalDateTime now = LocalDateTime.now();
                Duration duration = Duration.between(now, appraiseTime);
                if (Math.abs(duration.toDays()) >= 7) {
                    vo.setHasAppraise(true);
                } else {
                    LocalDateTime plusDays = appraiseTime.plusDays(7);
                    duration = Duration.between(now, plusDays);
                    vo.setHasAppraise(false);
                    vo.setCountdown(Math.abs(duration.toDaysPart()) + "天" + Math.abs(duration.toHoursPart()) + "时" + Math.abs(duration.toMinutesPart()) + "分后可评价");
                }
            }
        }
        return AjaxResult.success(voPage);

    }
}
